/****************************************************************************
** Copyright (c) quickfixengine.org  All rights reserved.
**
** This file is part of the QuickFIX FIX Engine
**
** This file may be distributed under the terms of the quickfixengine.org
** license as defined by quickfixengine.org and appearing in the file
** LICENSE included in the packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.quickfixengine.org/LICENSE for licensing information.
**
** Contact ask@quickfixengine.org if any conditions of this licensing are
** not clear to you.
**
****************************************************************************/

#include "SocketAcceptor.h"
#include "SocketInitiator.h"
#include "SessionSettings.h"
#include "FileLog.h"

#include "FileStore.h"
#include "Utility.h"
#include <iostream>
#include <fstream>
#include <memory>
#include "at_application.h"
#include <Utility.h>

#ifdef _MSC_VER
#pragma warning( disable : 4503 )
#endif
typedef std::auto_ptr < FIX::Acceptor > AcceptorPtr;
typedef std::auto_ptr < FIX::Initiator > InitiatorPtr;
static THREAD_PROC startThread(void *p);
bool bRun = true;
unsigned int Application::gblSeqNo  = 0;
int main( int argc, char** argv )
{
	std::string file;

	if ( getopt( argc, argv, "+f:" ) == 'f' )
		file = optarg;
	else
	{
		std::cout << "usage: " << argv[ 0 ]
		<< " -f FILE" << std::endl;
		return 1;
	}

	unsigned m_threadid;
	 if( !FIX::thread_spawn( &startThread, (void*)file.c_str(), m_threadid ) )
		 throw FIX::RuntimeError("Unable to spawn thread");
	 FIX::thread_join(m_threadid);
}
static THREAD_PROC startThread(void *p)
{
	try
	{
		const char* file = (const char*) p;
		FIX::SessionSettings settings( file );
		Application application;
		FIX::FileStoreFactory factory( settings );
		FIX::FileLogFactory   logFactory ( settings ); //to file
		//FIX::ScreenLogFactory logFactory( true, true, true ); // to std::cout



		if( settings.get().has( FIX::CONNECTION_TYPE ) && settings.get().getString(FIX::CONNECTION_TYPE, false ) == "acceptor")
		{
			AcceptorPtr pAcceptor;
			//pAcceptor = std::auto_ptr < FIX::Acceptor >( new FIX::SocketAcceptor( application, factory, settings, logFactory ) );
			pAcceptor = std::auto_ptr < FIX::Acceptor >( new FIX::SocketAcceptor( application, factory, settings ) );
			pAcceptor->start();

			while ( bRun ) 
			{
				getchar();
				break;
				FIX::process_sleep( 1 );
			}
			pAcceptor->stop();

		}
		else
		{
			InitiatorPtr pInitiator;
			pInitiator = std::auto_ptr < FIX::Initiator >( new FIX::SocketInitiator( application, factory, settings, logFactory ) );
			pInitiator->start();
			while ( bRun ) 
			{
				getchar();
				break;
				FIX::process_sleep( 1 );
			}
			pInitiator->stop();
		}

	}
	catch ( std::exception & e )
	{
		std::cout << e.what();
	}

	return 0;
}
